#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "symbolMgt.h"

#define TABLESIZE 10

/* Définition des types */
int TREE_NODE = 1;
int TREE_STRUCT = 2;

/* Déclaration du type Symbol */
typedef struct symbol {  
  char * name;
  int type;
  void *pointeur;
  struct symbol *next;
} Symbol;

/* Initialisation de la table de symbole */
static Symbol stockagePremierElement;
static Symbol * table = &stockagePremierElement;

/* Var used to get "nextTreeStruct" */
static int nextTreeStruct = 1;

/* Fonction pour insérer un symbole */
int insertInSymbolTable(char * symbolName, int type) {
  Symbol *courantP = table;
  Symbol *newP = malloc(sizeof(Symbol));
  if (newP == NULL) { fprintf(stderr,"Error allocating merroring"); abort(); } 
  /* Test if symbol is present */
  /* if (isInSymbolTable(symbolName) == 1) {
    fprintf(stderr,"%s already present\n",symbolName);
    free(newP);
    newP = NULL;
    return EXIT_FAILURE;
  } */
  /* Symbol is NOT present in table */
  else {
    /* Defining new element */
    newP->name = malloc((strlen(symbolName) + 1) * sizeof(char));
    if (newP->name  == NULL) { fprintf(stderr,"Error allocating merroring"); abort(); }
    strcpy(newP->name,symbolName);
    /* Saving type */
    newP->type = type;
    /* Looking where to place it */ 
    while (courantP->next != NULL) { /* Not sorting */
    //while ((courantP->next != NULL) && ((courantP->name != NULL) || (strcmp(courantP->name,symbolName) < 0))) {
      courantP = courantP->next;
    } 
    if (courantP->next != NULL) { newP->next = courantP->next; }
    courantP->next = newP;
  
    fprintf(stderr,"%s inserted\n",newP->name);
    return EXIT_SUCCESS;
  }
}
Symbol * getPointerForSymbol(char * symbolName) {
  Symbol *courantP = table;
  do {
    if (courantP == NULL) { return NULL; }
    if (courantP->name != NULL) { 
		 if (strcmp(symbolName,courantP->name) == 0) {
		   /* symbol Found ! */
		   return courantP;
		 }
    }
    courantP = courantP->next;
  } while (courantP != NULL);
  return NULL; /* symbol not found */
}
Symbol * getPointerForType(int type, int times) {
  int i=0;
  Symbol *courantP = table;
  do {
    if (courantP == NULL) { return NULL; }
		 if (courantP->type == type) {
		   /* symbol Found ! */
         i++;
		   if (times == i) {
           return courantP;
         }
    }
    courantP = courantP->next;
  } while (courantP != NULL);
  return NULL; /* symbol not found */
}
int isInSymbolTable(char * symbolName) {
  Symbol *pointeur = getPointerForSymbol(symbolName);
  if (pointeur == NULL) {
    return 0;
  }
  else {
    return 1;
  }
}
char *printType(int type) {
 if (type == 1) { return "TREE_NODE"; }
 else { return "TREE_STRUCT"; }
}
void printSymbolTable() {
  Symbol *courantP = table;
  courantP = courantP->next;
  while (courantP->next != NULL) {
    fprintf(stdout,"%s %s %p\n",courantP->name,printType(courantP->type),courantP->pointeur);
    courantP = courantP->next;
  } 
  fprintf(stdout,"%s %s %p\n",courantP->name,printType(courantP->type),courantP->pointeur); /* UGLY but works */
}
int setRefForSymbolInTable(char *symbolName, void * ref) {
  Symbol *courantP = getPointerForSymbol(symbolName);
  if (courantP == NULL) {
    return 0; /* Fail */
  }
  else {
    courantP->pointeur = ref;
    return 1; /* Success */
  }
}
void * getRefForSymbolInTable(char * symbolName) {
  Symbol *courantP = getPointerForSymbol(symbolName);
  if (courantP == NULL) {
    return NULL;
  }
  else {
    return courantP->pointeur;
  }
}
char * firstTreeStructSymbolName () {
  Symbol *courantP = getPointerForType(TREE_STRUCT,1); /* 1 to get First */
  nextTreeStruct = 1;
  if (courantP == NULL) { return NULL; }
  else {
    return courantP->name;
  }
}
char * nextTreeStructSymbolName() {
  nextTreeStruct++;
  return getPointerForType(TREE_STRUCT,nextTreeStruct-1)->name;
}
